import notifyBus from './notifyBus'

const SHARE_PROVIDER_KEY = 'shareProvider'
const SHARE_USE_KEY = 'shareUse'
const ShareData = () => {}

ShareData.install = (Vue) => {
  /**
   * **数据提供方**
   * 使用方式如：
   * shareProvider () {
   *  return {
   *    key: 'some-key',
   *    data: {
   *      someData: 'someValue'
   *    }
   *   }
   * },
   */
  Vue.mixin({
    beforeCreate () {
      if (this.$options[SHARE_PROVIDER_KEY] !== undefined) {
        let type = typeof this.$options[SHARE_PROVIDER_KEY]
        this._hasShareProvider = true
        if (typeof this.$options.computed === 'undefined') {
          this.$options.computed = {}
        }
        this.$options.computed.$shareProvider = type === 'function'
          ? this.$options[SHARE_PROVIDER_KEY]
          : () => this.$options[SHARE_PROVIDER_KEY]
      }
    },

    beforeMount () {
      if (this._hasShareProvider) {
        notifyBus.update(this.$shareProvider.key, 'getData', this.$shareProvider.data)
      }
    },

    mounted () {
      if (this._hasShareProvider) {
        this.$watch('$shareProvider', (newVal) => {
          notifyBus.update(newVal.key, 'getData', newVal.data)
        })
      }
    },

    beforeDestroy () {
      if (this._hasShareProvider) {
        notifyBus.update(this.$shareProvider.key, 'leave')
      }
    }
  })

  /**
   * **消费者方**
   * 使用方式如：
   * shareUse () {
   *  return {
   *    key: 'some-key',
   *    getData(bindData) {
   *      // something...
   *    }
   *   }
   * },
   */
  Vue.mixin({
    beforeCreate () {
      if (this.$options[SHARE_USE_KEY] !== undefined) {
        let type = typeof this.$options[SHARE_USE_KEY]
        this._shareUse = true
        if (typeof this.$options.computed === 'undefined') {
          this.$options.computed = {}
        }
        this.$options.computed.$shareUse = type === 'function'
          ? this.$options[SHARE_USE_KEY]
          : () => this.$options[SHARE_USE_KEY]
      }
    },

    beforeMount () {
      if (this._shareUse) {
        notifyBus.on(this.$shareUse.key, 'getData', this.$shareUse.getData)
        notifyBus.on(this.$shareUse.key, 'leave', this.$shareUse.providerLeave)
      }
    },

    mounted () {
      if (this._shareUse) {
        this.$watch('$shareUse', (newVal, oldVal) => {
          if (oldVal) {
            notifyBus.off(oldVal.key, oldVal.getData)
          }
          if (newVal) {
            notifyBus.on(newVal.key, newVal.getData)
          }
        })
      }
    },

    beforeDestroy () {
      if (this._shareUse) {
        notifyBus.off(this.$shareUse.key, 'getData', this.$shareUse.getData)
        notifyBus.off(this.$shareUse.key, 'leave', this.$shareUse.providerLeave)
      }
    }
  })
}

export default ShareData
